﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Xml;

namespace SHomeWorkshop.LunarPresentation.Expressions
{
    public class LogicCross : CanvasExpression
    {
        public LogicCross(SubPanel rootPanel, SubPanel parentPanel, Editor editor)
            : base(rootPanel, parentPanel, editor)
        {
            //绘制两个交叉外接圆。
            leftEllipse = new Ellipse();
            leftEllipse.StrokeThickness = 2;
            leftEllipse.Stroke = ExForeground;
            leftEllipse.Fill = System.Windows.Media.Brushes.Transparent;
            leftEllipse.Cursor = Cursors.Hand;
            leftEllipse.MouseRightButtonDown += Ellipse_MouseRightButtonDown;
            leftEllipse.MouseLeftButtonDown += Ellipse_MouseLeftButtonDown;
            leftEllipse.MouseLeftButtonUp += Ellipse_MouseLeftButtonUp;

            rightEllipse = new Ellipse();
            rightEllipse.StrokeThickness = 2;
            rightEllipse.Stroke = ExForeground;
            rightEllipse.Fill = System.Windows.Media.Brushes.Transparent;
            rightEllipse.Cursor = Cursors.Hand;
            rightEllipse.MouseRightButtonDown += Ellipse_MouseRightButtonDown;
            rightEllipse.MouseLeftButtonDown += Ellipse_MouseLeftButtonDown;
            rightEllipse.MouseLeftButtonUp += Ellipse_MouseLeftButtonUp;

            basePanel.Children.Add(leftEllipse);
            basePanel.Children.Add(rightEllipse);

            Canvas.SetZIndex(leftEllipse, 1);
            Canvas.SetZIndex(rightEllipse, 2);

            //三个主面板。
            middlePanel = new SubPanel(rootPanel, parentPanel, editor, this);
            leftPanel = new SubPanel(rootPanel, parentPanel, editor, this);
            rightPanel = new SubPanel(rootPanel, parentPanel, editor, this);

            middlePanel.SizeChanged += eachPanel_SizeChanged;
            leftPanel.SizeChanged += eachPanel_SizeChanged;
            rightPanel.SizeChanged += eachPanel_SizeChanged;

            basePanel.Children.Add(middlePanel);
            basePanel.Children.Add(leftPanel);
            basePanel.Children.Add(rightPanel);

            Canvas.SetZIndex(middlePanel, 101);
            Canvas.SetZIndex(leftPanel, 102);
            Canvas.SetZIndex(rightPanel, 103);

            RefreshSubPanelRelatios();

            this.chineseName = "交叉关系式";
        }

        void Ellipse_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            // 接收拖动来的公式。
            Globals.DropExpression(this);
        }

        void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            //准备拖动公式。
            Globals.dragSourceExpression = this;
            this.Editor.SelectedExpression = this;
            e.Handled = true;
        }

        void Ellipse_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.Editor.SelectedExpression = this;
            e.Handled = true;
        }

        /// <summary>
        /// 包含左、中两个子面板的圆。
        /// </summary>
        private Ellipse leftEllipse;

        /// <summary>
        /// 包含中、右两个子面板的圆。
        /// </summary>
        private Ellipse rightEllipse;

        public override Brush ExForeground
        {
            get
            {
                return base.ExForeground;
            }
            set
            {
                UpdateExForegroundWithoutXmlChanging(value);
                UpdateExForegroundToXmlData(value);
                Editor.IsModified = true;
            }
        }

        public override void UpdateExForegroundWithoutXmlChanging(Brush value)
        {
            base.UpdateExForegroundWithoutXmlChanging(value);

            base.exForeground = value;
            this.leftEllipse.Stroke = value;
            this.rightEllipse.Stroke = value;
        }

        void eachPanel_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
        {
            // 重新计算BasePanel（Canvas）的尺寸。
            if (middlePanel == null || leftPanel == null || rightPanel == null) return;

            double maxDiameter = 0;

            double width, height;

            double middleDiameter, leftDiameter, rightDiameter;

            width = middlePanel.ActualWidth; height = middlePanel.ActualHeight;
            middleDiameter = Math.Sqrt(width * width + height * height);
            if (maxDiameter < middleDiameter) maxDiameter = middleDiameter;

            width = leftPanel.ActualWidth; height = leftPanel.ActualHeight;
            leftDiameter = Math.Sqrt(width * width + height * height);
            if (maxDiameter < leftDiameter) maxDiameter = leftDiameter;

            width = rightPanel.ActualWidth; height = rightPanel.ActualHeight;
            rightDiameter = Math.Sqrt(width * width + height * height);
            if (maxDiameter < rightDiameter) maxDiameter = rightDiameter;
            // 已取出maxDiameter。

            double redius = maxDiameter / 2;//半径

            basePanel.Height =
                (leftDiameter > rightDiameter) ?
                (leftDiameter + middleDiameter) :
                (rightDiameter + middleDiameter) + 20;// 上下各留空白10.

            basePanel.Width = leftDiameter + middleDiameter + rightDiameter + 20;// 左右各留空白10.

            basePanel.InvalidateArrange();
            basePanel.UpdateLayout();

            double halfWidth = basePanel.ActualWidth / 2;
            double halfHeight = basePanel.ActualHeight / 2;

            // 刷新各子面板位置。
            Point leftPt = new Point(10 + leftDiameter / 2, halfHeight);
            Point middlePt = new Point(10 + leftDiameter + middleDiameter / 2, halfHeight);
            Point rightPt = new Point(basePanel.ActualWidth - 10 - rightDiameter / 2, halfHeight);

            Canvas.SetLeft(leftPanel, leftPt.X - leftPanel.ActualWidth / 2);
            Canvas.SetTop(leftPanel, leftPt.Y - leftPanel.ActualHeight / 2);

            Canvas.SetLeft(middlePanel, middlePt.X - middlePanel.ActualWidth / 2);
            Canvas.SetTop(middlePanel, middlePt.Y - middlePanel.ActualHeight / 2);

            Canvas.SetLeft(rightPanel, rightPt.X - rightPanel.ActualWidth / 2);
            Canvas.SetTop(rightPanel, rightPt.Y - rightPanel.ActualHeight / 2);

            // 重置两个交叉外接圆的位置、大小。
            leftEllipse.Width = leftEllipse.Height = leftDiameter + middleDiameter;
            Canvas.SetLeft(leftEllipse, 11);
            Canvas.SetTop(leftEllipse, halfHeight - (leftDiameter + middleDiameter) / 2);

            rightEllipse.Width = rightEllipse.Height = middleDiameter + rightDiameter;
            Canvas.SetLeft(rightEllipse, 10 + leftDiameter);
            Canvas.SetTop(rightEllipse, halfHeight - (middleDiameter + rightDiameter) / 2);
        }

        protected override void BuildChildren()
        {
            base.BuildChildren();

            if (this.XmlData == null) return;

            XmlNodeList childrenNodes = this.XmlData.SelectNodes("Expression");

            if (childrenNodes == null || childrenNodes.Count <= 0) return;

            foreach (XmlNode node in childrenNodes)
            {
                XmlAttribute attrOfLocation = node.GetAttribute("Location");
                if (attrOfLocation == null) continue;

                switch (attrOfLocation.Value)
                {
                    case "Left":
                        {
                            if (leftPanel != null) leftPanel.XmlData = node; break;
                        }
                    case "Middle":
                        {
                            if (middlePanel != null) middlePanel.XmlData = node; break;
                        }
                    case "Right":
                        {
                            if (rightPanel != null) rightPanel.XmlData = node; break;
                        }
                }
            }

            RefreshSubPanelRelatios();//防止“隐藏附属面板”字段值被修改后未刷新。
        }

        private SubPanel middlePanel;

        public SubPanel MiddlePanel
        {
            get { return middlePanel; }
        }

        private SubPanel leftPanel;

        public SubPanel LeftPanel
        {
            get { return leftPanel; }
        }

        private SubPanel rightPanel;

        public SubPanel RightPanel
        {
            get { return rightPanel; }
        }

        protected override void RefreshSubPanelRelatios()
        {
            this.SubPanels.Clear();// 此方法可能被重复调用。

            this.subPanels.Add(middlePanel);
            this.subPanels.Add(leftPanel);
            this.subPanels.Add(rightPanel);

            this.leftPanel.RightSubPanel = middlePanel;
            this.middlePanel.LeftSubPanel = leftPanel;
            this.middlePanel.RightSubPanel = rightPanel;
            this.rightPanel.LeftSubPanel = middlePanel;

            this.firstSubPanel = this.leftPanel;
            this.lastSubPanel = this.rightPanel;
        }

        public override void SetProperty(string propertyName, string value)
        {
            base.SetProperty(propertyName, value);

            //下面是示例。作为中间类，可参考基类与派生类中此方法的实现。
            //switch (propertyName)
            //{
            //    case "Indent":
            //        {
            //            this.Indent = int.Parse(value);
            //            break;
            //        }
            //}
        }
    }
}
